
package com.probiz.estore.customer.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;

import com.probiz.estore.Constants;
import com.probiz.estore.common.helper.ConfigUtil;
import com.probiz.estore.common.model.customer.Customer;
import com.probiz.estore.common.model.customer.Membership;
import com.probiz.estore.common.model.customer.ShopPoint;
import com.probiz.estore.common.model.customer.ValidationSession;
import com.probiz.estore.common.model.system.AppUser;
import com.probiz.estore.common.util.DateUtil;
import com.probiz.estore.core.search.SearchCriteria;
import com.probiz.estore.core.util.StringUtil;
import com.probiz.estore.customer.dao.CustomerDao;
import com.probiz.estore.customer.model.CustomerFullyModel;
import com.probiz.estore.customer.model.CustomerSearchCriteria;
import com.probiz.estore.customer.service.CustomerAttrValueManager;
import com.probiz.estore.customer.service.CustomerManager;
import com.probiz.estore.customer.service.MembershipManager;
import com.probiz.estore.customer.service.ShopPointManager;
import com.probiz.estore.customer.service.ValidationSessionManager;
import com.probiz.estore.system.service.MsgSendManager;
import com.probiz.estore.system.service.impl.AppUserManagerImpl;
import com.probiz.estore.system.util.MsgTemplateConstants;

/**
 * Customer Business Delegate (Proxy) implementation to handle communication
 * between web and persistence layer. Implementation of CustomerManager
 * interface. Developer introduced interfaces should be declared here. Won't get
 * overwritten.
 */
public class CustomerManagerImpl extends AppUserManagerImpl<Customer> implements CustomerManager {

	private MembershipManager			membershipManager			= null;

	private ValidationSessionManager	validationSessionManager	= null;

	private ShopPointManager			shopPointManager			= null;

	private CustomerDao					customerDao					= null;
	
	private CustomerAttrValueManager           customerAttrValueManager             =  null;
	
	private MsgSendManager msgSendManager = null;
	
	public void setMembershipManager(MembershipManager membershipManager) {
		this.membershipManager = membershipManager;
	}

	public void setValidationSessionManager(
			ValidationSessionManager validationSessionManager) {
		this.validationSessionManager = validationSessionManager;
	}

	public void setShopPointManager(ShopPointManager shopPointManager) {
		this.shopPointManager = shopPointManager;
	}

	public void setMsgSendManager(MsgSendManager msgSendManager) {
		this.msgSendManager = msgSendManager;
	}

	public void setCustomerAttrValueManager(
			CustomerAttrValueManager customerAttrValueManager) {
		this.customerAttrValueManager = customerAttrValueManager;
	}

	@Override
	protected void initManager() {
		this.dao = customerDao;
	}

	@Override
	protected void preDelete(Customer entity) {
		
	}

	@Override
	protected void preSave(Customer entity) {
		
	}

	public void setCustomerDao(CustomerDao customerDao) {
		this.customerDao = customerDao;
		super.appUserDao = customerDao;
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.customer.service.CustomerManager#searchByCriteria(com.probiz.estore.customer.model.CustomerSearchCriteria, com.probiz.estore.core.search.SearchCriteria)
	 */
	public List<Customer> searchByCriteria(CustomerSearchCriteria customerSearchCriteria, SearchCriteria searchCriteria){
		return customerDao.searchByCriteria(customerSearchCriteria, searchCriteria);
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.customer.service.CustomerManager#searchByCriteriaForController(com.probiz.estore.customer.model.CustomerSearchCriteria, com.probiz.estore.core.search.SearchCriteria)
	 */
	public List<Customer> searchByCriteriaForController(CustomerSearchCriteria customerSearchCriteria, SearchCriteria searchCriteria){
		 if (searchCriteria.getPageNo() < 1)  //如果是翻页过前，就拿第一页就可以。
	        {
	            searchCriteria.changePaging(1, searchCriteria.getPageSize());
	        }
		    List<Customer> result = searchByCriteria(customerSearchCriteria, searchCriteria);
		    if (result == null|| result.size() == 0 )
		    {
		        if (searchCriteria.getPageNo() > searchCriteria.getTotalPageCount()) //如果是翻页前，就拿最后一页就可以。
		        {
		            searchCriteria.changePaging(searchCriteria.getTotalPageCount(), searchCriteria.getPageSize());
		            result = searchByCriteria(customerSearchCriteria, searchCriteria);
		        }
		    }
			return result;
	}

	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.customer.service.CustomerManager#getByAppUserId(java.lang.Integer)
	 */
	public Customer getByAppUserId(Integer appUserId) {
		return customerDao.getByAppUserId(appUserId);
	}
	/*
	 * @see com.p)robiz.estore.customer.service.CustomerManager#getCustomerByUsername(java.lang.String)
	 */
	public Customer getCustomerByUsername(String username) {
		return customerDao.getUniqueByProperty("username", username);
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.customer.service.CustomerManager#getCustomerByEmail(java.lang.String)
	 */
	public Customer getCustomerByEmail(String email) {
		return customerDao.getUniqueByProperty("email", email);
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.customer.service.CustomerManager#getCustomerCountsByMembershipId(java.lang.Integer)
	 */
	public Integer getCustomerCountsByMembershipId(Integer membershipId) {
		return customerDao.countByFilter(Customer.FilterHqlName.COUNT_BY_MEMBERSHIP_ID, membershipId).intValue();
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.customer.service.CustomerManager#saveCustomerPreferredLanguage(java.lang.Integer, java.lang.String)
	 */
	public void saveCustomerPreferredLanguage(Integer customerId,String preferLanguage) {
		customerDao.saveCustomerPreferredLanguage(customerId, preferLanguage);
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.customer.service.CustomerManager#doRegisterCustomer(com.probiz.estore.customer.model.CustomerFullyModel)
	 */
	public Map<String,Object> doRegisterCustomer(CustomerFullyModel model) throws Exception{
		Customer customer=model.getCustomer();
		Map<String, Object> returnMsgs = new HashMap<String, Object>();
		
		Short activeMode = ConfigUtil.getInstance().getCustomerRegisterActiveMode();
		if (Constants.CUSTOMER_ACTIVE_EMAIL.equals(activeMode)) {
			//------------邮件激活--------------
			//增加一个客户
			addCustomer(model, Constants.STATUS_INACTIVE);
			//产生一个激活的令牌
			String email = customer.getEmail();
			sendValidationMail(email);
			
		}else if (Constants.CUSTOMER_ACTIVE_NOW.equals(activeMode)) {
			//------------立即激活--------------
			//增加一个客户
			addCustomer(model, Constants.STATUS_ACTIVE);
		}else{
			//------------管理员手工激活--------------
			//增加一个客户
			addCustomer(model, Constants.STATUS_INACTIVE);
		}	
		
		returnMsgs.put("activeMode", activeMode);
		returnMsgs.put("email", customer.getEmail());
		returnMsgs.put("username", customer.getUsername());
		return returnMsgs;
	}
	
	public void sendValidationMail(String email) {
		ValidationSession vs = validationSessionManager.doGenerateUrlByEmail(email, ValidationSession.TYPE_CUSTOMER_ACTIVE);
		Map map = new HashMap();
		map.put("vs", vs);
		//发送邮件
		msgSendManager.sendMsg(MsgTemplateConstants.MESSAGE_FRONT_USER_ACTIVATION, map, new String[]{email}, null, null);
		//mailEngine.sendSimpleTemplateMail("customer/activateUser.vm", map, null, null, email);
	}

	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.customer.service.CustomerManager#addCustomer(com.probiz.estore.customer.model.CustomerFullyModel, java.lang.Short)
	 */
	public Customer addCustomer(CustomerFullyModel model, Short status){
		Customer customer=model.getCustomer();
		
		customer.setPassword(StringUtil.encodePassword(customer.getPassword(), ConfigUtil.getInstance().getPasswordEncryptionAlgorithm()));
		customer.setUserType(AppUser.USER_TYPE_CUSTOMER);
		customer.setStatus(status);
		customer.setIsLocked(AppUser.CONST_UNLOCKED);
		customer.setDeleted(Customer.CONST_UNDELETED);

		if (customer.getMembershipId() == null) {
			//设置默认的membership
			customer.setMembership(membershipManager.getBaseMembership());
		}
		save(customer);
		
		// start:保存积分信息
		ShopPoint shopPoint = customer.getShopPoint();
		if (shopPoint == null) {
			shopPoint = new ShopPoint();
			shopPoint.setTotal(0);
			shopPoint.setGainedTotal(0);
			shopPoint.setUsedTotal(0);
		}
		shopPointManager.save(shopPoint);
		customer.setShopPoint(shopPoint);
		
		save(customer);
		// end: 保存积分信息
		
		//--------这时候可以赠送积分，不需理会是否已激活---------------
		shopPointManager.updateShopPoint(customer, ConfigUtil.getInstance().getRegistrationShopPointAmount(), ShopPoint.TYPE_CUSTOMERREGISTER, null);
		
		
		//start:保存自定义属性
		customerAttrValueManager.saveCustomerAttrValueFromRequest(customer,model.getAttributeValues());
		//end:  保存自定义属性
		
		
//		// add the shop point history for this new customer.
//		shopPointHistoryManager.saveNewShopPointHistory(Constants.ShopPoint_Type_Registration, customer);
//
//		wishlistManager.addDefaultWishlist(customer);
		
		return customer;
	}

	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.customer.service.CustomerManager#saveFully(com.probiz.estore.customer.model.CustomerFullyModel)
	 */
	public Customer saveFully(CustomerFullyModel model){
		Customer customer=model.getCustomer();
		// start:保存积分信息
		ShopPoint shopPoint = customer.getShopPoint();
		if (shopPoint == null) {
			shopPoint = new ShopPoint();
			shopPoint.setTotal(0);
			shopPoint.setGainedTotal(0);
			shopPoint.setUsedTotal(0);
			shopPointManager.save(shopPoint);
			customer.setShopPoint(shopPoint);
		}
		
		save(customer);
		// end: 保存积分信息
		//start:保存自定义属性
		customerAttrValueManager.saveCustomerAttrValueFromRequest(customer,model.getAttributeValues());
		//end:  保存自定义属性
		return customer;
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.customer.service.CustomerManager#saveFullyForImport(com.probiz.estore.common.model.customer.Customer)
	 */
	public Customer saveFullyForImport(Customer customer){
		boolean isNew = (null==customer.getAppuserId())?true:false;
		customer.setUserType(AppUser.USER_TYPE_CUSTOMER);
		customer.setStatus(ConfigUtil.getInstance().getCustomerImportDefaultUserStatus());
		customer.setIsLocked(AppUser.CONST_UNLOCKED);
		customer.setDeleted(Customer.CONST_UNDELETED);
		// start:保存积分信息
		ShopPoint shopPoint = customer.getShopPoint();
		if (shopPoint == null) {
			shopPoint = new ShopPoint();
			shopPoint.setTotal(0);
			shopPoint.setGainedTotal(0);
			shopPoint.setUsedTotal(0);
			shopPointManager.save(shopPoint);
			customer.setShopPoint(shopPoint);
		}

		saveImport(customer);
		// end: 保存积分信息
		
		if(isNew){
			//--------这时候可以赠送积分，不需理会是否已激活---------------
			shopPointManager.updateShopPoint(customer, ConfigUtil.getInstance().getRegistrationShopPointAmount(), ShopPoint.TYPE_CUSTOMERREGISTER, null);
		}	
		
		return customer;
		
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.customer.service.CustomerManager#deleteFully(com.probiz.estore.common.model.customer.Customer)
	 */
	public void deleteFully(Customer customer){
		//在原账号和邮箱后增加后缀
		String suffix = "-Del"+DateUtil.fmtTodayToSix()+RandomStringUtils.random(6,false,true);
		customer.setUsername(customer.getUsername()+suffix);
		customer.setEmail(customer.getEmail()+suffix);
		this.save(customer);
		this.flush();//必须flush，否则上面的save会被撤销。
		this.delete(customer);
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.customer.service.CustomerManager#doActiveCustomer(com.probiz.estore.common.model.customer.Customer)
	 */
	public void doActiveCustomer(Customer customer){
		customer.setStatus(Constants.FLAG_TRUE);
		save(customer);
		Map<String, Object> model = new HashMap<String, Object>();
		model.put("customer", customer);
		model.put("domain", ConfigUtil.getInstance().getStoreFrontSiteUrl());
		msgSendManager.sendMsg(MsgTemplateConstants.MESSAGE_BACKSTAGE_USER_ACTIVATION, model, new String[]{customer.getEmail()}, new String[]{customer.getAppuserId().toString()}, new String[]{customer.getMobilephone()});
	}
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.customer.service.CustomerManager#doForbidCustomer(com.probiz.estore.common.model.customer.Customer)
	 */
	public void doForbidCustomer(Customer customer){
		customer.setStatus(Constants.FLAG_FALSE);
		save(customer);
	}


	public List<Customer> findExportCustomer(Date lastExecuteTime) {
		return customerDao.findExportCustomer(lastExecuteTime);
	}

	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.customer.service.CustomerManager#doImportCustomersForEai(java.util.List)
	 */
	public void doImportCustomersForEai(
			List<com.probiz.estore.eai.customer.generated.Customer> customerList) {
		for(com.probiz.estore.eai.customer.generated.Customer customer : customerList){
			    doImportCustomerForEai(customer);
		}
		
	}
	private void doImportCustomerForEai(com.probiz.estore.eai.customer.generated.Customer customer){
		String code=customer.getCode();
		Customer c = customerDao.getUniqueByProperty("customerCode", code);
		String tmpEmail= StringUtils.isNotBlank(customer.getEmail())? customer.getEmail(): customer.getName()+"@"+(new java.util.Date()).getTime();
		if(c==null){//new
			String sortCode=customer.getSortCode();//对应membership的membershipCode
			Membership membership=this.membershipManager.getMembershipByCode(sortCode);
			
			c=new Customer();
			c.setUsername(customer.getName());			
			
			c.setEmail(tmpEmail);
			c.setFax(customer.getFax());
			c.setUserType(new Short("0"));
			c.setTelephone(customer.getPhone());
			c.setZip(customer.getPostcode());			
			c.setCustomerCode(code);
			c.setDeleted(new Short("0"));
			c.setMembership(membership);	
			c.setCreateTime(new java.util.Date());
			c.setStatus(Constants.STATUS_ACTIVE);
			c.setIsLocked(new Short("0"));			
		}else{
			c.setUsername(customer.getName());
			c.setEmail(tmpEmail);
			c.setFax(customer.getFax());
			c.setTelephone(customer.getPhone());
			c.setZip(customer.getPostcode());
				
			
		}
		
		customerDao.save(c);
	}
	
	 public List<String> searchCustomerEmails(int pageNo, int pageSize, List<String> newsletterGroupIds){
		 return customerDao.searchCustomerEmails(pageNo, pageSize, newsletterGroupIds);
	 }
	 
	public Long countCustomerTotal(){
		return customerDao.countByFilter(Customer.FilterHqlName.COUNT_CUSTOMER_TOTAL);
	}

	/*
	 * 
	 */
	public List<Customer> searchByCriteria4MembershipLevel(SearchCriteria sc){
		List<Customer>  list = customerDao.searchByCriteria(sc);
		for(Customer customer: list){
			try{
				this.initialize(customer);
				this.initialize(customer.getMembership());
				this.initialize(customer.getShopPoint());
			}catch(Exception ex){
				ex.printStackTrace();
			}
		}
		return list;
	}
		
	public List<Customer> getListByDeleted() {
		return this.customerDao.getListByDeleted();
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.probiz.estore.customer.service.CustomerManager#getCustomer4Login(java.lang.String, java.lang.String)
	 */
	public Customer getCustomer4Login(String username, String password){
		
		Customer customer = getUserByName(username);

		if ( null == customer || !AppUser.USER_TYPE_CUSTOMER.equals(customer.getUserType()) || Constants.STATUS_INACTIVE.equals(customer.getStatus()) ) {
			return null;
		}

		String enPassword = StringUtil.encodePassword(password, ConfigUtil.getInstance().getPasswordEncryptionAlgorithm());

		if (enPassword.equals(customer.getPassword())) {
			return customer;
		}
		
		return null;
	}
}